package com.example.libbase.net.response;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;

import com.example.libbase.net.exception.ApiException;
import com.example.libbase.utils.RefletUtil;

import org.jetbrains.annotations.NotNull;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * 封装响应数据类型转换
 * Obervable<IResponse<T>> --> Observable<T>
 * 实现：
 * 1.对线程进行切换，达到代码复用
 * 2.对AxJava的生命周期进行管理，防止内存泄漏
 * 3.对响应数据进行同意处理，获取真正想要的data进行业务处理
 */
public class ResponseTransformer<T> implements ObservableTransformer<IResponse<T>, T>, LifecycleObserver {

    final CompositeDisposable compositeDisposable = new CompositeDisposable();

    /**
     * 观察页面是否销毁，页面销毁时调用
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestroy() {
        if (!compositeDisposable.isDisposed()) {
            compositeDisposable.dispose();
        }
    }

    /**
     * 封装响应数据类型转换
     *
     * @param upstream
     * @return
     */
    @NotNull
    @Override
    public ObservableSource<T> apply(@NotNull Observable<IResponse<T>> upstream) {
        return upstream.doOnSubscribe(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                // 每次执行订阅的时候执行
                compositeDisposable.add(disposable);
                // compositeDisposable有一个方法 ”compositeDisposable.dispose()“用于取消当前添加的全部disposable
            }
        }).onErrorResumeNext(new Function<Throwable, ObservableSource<? extends IResponse<T>>>() {
            @Override
            public ObservableSource<? extends IResponse<T>> apply(@NotNull Throwable throwable) throws Exception {
                // 出现异常时调用 异常统一处理（非业务性异常，比如我的代码写出了bug）
                return Observable.error(ApiException.handleException(throwable));
            }
        }).flatMap(new Function<IResponse<T>, ObservableSource<T>>() {
            @Override
            public ObservableSource<T> apply(@NotNull IResponse<T> response) throws Exception {
                // 对响应数据统一处理
                if (response.isSuccess()) {
                    if (response.getData() == null) {
                        // 业务请求可能成功了，但是data是null
                        // 通过反射手动创建data， 这个data一般没有实际用途
                        Class<?> clz = RefletUtil.analysisClassInfo(response);
                        T object = (T) clz.newInstance();
                    }
                    return Observable.just(response.getData());
                }
                return Observable.error(new ApiException(response.getCode(), response.getMsg()));
            }
        }).subscribeOn(Schedulers.io()) // 指定事件产生的线程（请求的线程）
                .observeOn(AndroidSchedulers.mainThread()); // 指定事件处理的线程（响应的线程）
    }

    public static <T> ResponseTransformer<T> obtain(LifecycleOwner lifecycleOwner) {
        // lifecycleOwner是被观察者，需要添加观察者
        ResponseTransformer<T> tResponseTransformer = new ResponseTransformer<>();
        lifecycleOwner.getLifecycle().addObserver(tResponseTransformer);

        return tResponseTransformer;
    }

}
